💡 AI 인사이트

🤖 AI가 여기에 결과를 출력합니다...

댓글 커뮤니티

쿠팡이벤트

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

검색

    로딩 중이에요... 🐣

    [코담] 웹개발·실전 프로젝트·AI까지, 파이썬·장고의 모든것을 담아낸 강의와 개발 노트

    19 포스트 수정 기능 (GET API로 수정 페이지 진입) | ✅ 편저: 코담 운영자

    19강 - 포스트 수정 기능 (GET API로 수정 페이지 진입)

    수정 - GET api 개발


    ✨ 이번 강의 목표

    • 포스트 수정 버튼 클릭 시, 기존 내용이 담긴 수정 페이지로 이동
    • 포스트 작성자만 수정 페이지 접근 가능하도록 제어
    • 폼에 기존 포스트 데이터 자동 삽입 (캡션, 이미지)

    1. 디렉토리 구조

    django_instagram/
    ├── static/js/posts/loadMorePosts.js
    ├── templates/posts/
    │   ├── urls.py
    │   ├── forms.py
    │   ├── views.py
    │   └── post_update.html
    

    2. 수정 페이지로 이동하는 JS 함수

    파일: loadMorePosts.js

    function postUpdatePage(postId){
      window.location.href = `/posts/${postId}/post_update/`;
    }
    
    • 특정 postId에 해당하는 수정 페이지로 클라이언트가 이동하게 합니다.
    • window.location.href를 이용해 브라우저를 강제 이동시킴

    3. URL 패턴 설정

    파일: urls.py

    path('<int:post_id>/post_update/', views.post_update, name='post_update'),
    
    • 수정 페이지 URL 경로는 <int:post_id>/post_update/
    • 이 URL은 post_update 뷰 함수와 연결됨

    4. 수정 폼 정의

    파일: forms.py

    from django import forms
    from .models import Post
    
    class UpdatePostForm(forms.ModelForm):
        class Meta:
            model = Post
            fields = ["caption", "image"]
            labels = {
                "caption": "내용",
                "image": "사진"
            }
    
        def clean_caption(self):
            caption = self.cleaned_data.get("caption")
            if len(caption) < 5:
                raise forms.ValidationError("내용은 최소 5자 이상이어야 합니다.")
            return caption
    
        def clean_image(self):
            image = self.cleaned_data.get("image")
            if image and not image.name.endswith((".png", ".jpg", ".jpeg")):
                raise forms.ValidationError("지원하는 이미지 형식은 PNG, JPG, JPEG입니다.")
            return image
    
    • 게시글 caption, image 필드 포함
    • clean 메서드를 통해 각각 유효성 검사 수행

    5. 뷰 함수 정의

    파일: views.py

    from django.shortcuts import render, get_object_or_404, redirect
    from django.contrib.auth.decorators import login_required
    from django.urls import reverse
    from . import models
    from .forms import UpdatePostForm
    
    @login_required
    def post_update(request, post_id):
        post = get_object_or_404(models.Post, pk=post_id)
        if post.author != request.user:
            return redirect(reverse('users:main'))
    
        if request.method == "GET":
            form = UpdatePostForm(instance=post)
            return render(request, 'posts/post_update.html', {'form': form, 'post': post})
    
    • 로그인 사용자만 접근 가능 (@login_required)
    • 작성자가 아닌 경우 메인 페이지로 리디렉션 처리
    • GET 요청이면 기존 데이터를 포함한 폼 반환

    6. 수정 페이지 템플릿

    파일: post_update.html

    {% extends "posts/base.html" %}
    {% load static %}
    
    {% block title %} 포스트 수정 {% endblock title %}
    
    {% block content %}
    <div class="flex justify-center items-center min-h-screen bg-gray-100">
        <div class="w-3/4 aspect-[4/3] bg-white rounded-lg shadow-md p-8">
            <h1 class="text-2xl font-bold text-gray-800 mb-6 text-center">게시글 수정</h1>
            
            <form action="{% url 'posts:post_update' post.id %}" method="post" enctype="multipart/form-data" class="space-y-6 w-4/6 mx-auto">
                {% csrf_token %}
                {{ form.non_field_errors }}
    
                <div>
                    <label for="id_caption" class="block text-sm font-medium text-gray-700 mb-1">내용</label>
                    <textarea id="id_caption" name="caption" class="w-full border-gray-300 rounded-lg shadow-sm focus:border-indigo-500 focus:ring-indigo-500" rows="12" required>{{ form.caption.value }}</textarea>
                    {% if form.caption.errors %}
                        <p class="text-sm text-red-500 mt-1">{{ form.caption.errors.0 }}</p>
                    {% endif %}
                </div>
    
                <div>
                    <label for="id_image" class="block text-sm font-medium text-gray-700 mb-1">사진</label>
                    {% if form.instance.image %}
                        <div class="mb-4">
                            <p class="text-sm text-gray-600">현재 이미지:</p>
                            <img src="{{ form.image.value.url }}" alt="Uploaded image preview" class="w-32 max-h-16 object-cover border border-gray-300 rounded-lg"/>
                        </div>
                    {% endif %}
                    <input id="id_image" type="file" name="image" class="w-full file:mr-4 file:py-2 file:px-4 file:rounded-lg file:border-0 file:bg-indigo-600 file:text-white file:font-medium file:cursor-pointer file:hover:bg-indigo-500"/>
                    {% if form.image.errors %}
                        <p class="text-sm text-red-500 mt-1">{{ form.image.errors.0 }}</p>
                    {% endif %}
                </div>
    
                <button type="submit" class="w-full bg-indigo-600 text-white font-semibold rounded-lg py-3 text-center shadow-md hover:bg-indigo-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">수정하기</button>
            </form>
        </div>
    </div>
    {% endblock content %}
    
    • 기존 caption은 textarea에 출력됨
    • 기존 이미지가 있다면 preview 제공
    • 수정 완료 버튼을 클릭하면 POST 요청 발생

    ✅ 전체 흐름 요약

    1. JavaScript: postUpdatePage(postId) → 수정 URL로 이동
    2. URL: <int:post_id>/post_update/views.post_update
    3. View: 작성자 확인 + 기존 Post 인스턴스를 폼에 전달
    4. Template: caption, image 포함된 폼 출력
    5. Form 유효성: caption 최소 5자, 이미지 확장자 검사

    👉 다음 강의에서는 POST 방식으로 수정 결과를 저장하고 리디렉션 처리하는 작업을 진행합니다.

    TOP
    preload preload